package com.bicon.botu.finance.payment.unionpay;

import com.bicon.botu.finance.payment.entity.UnionpayDto;
import com.bicon.botu.finance.payment.unionpay.sdk.AcpService;
import com.bicon.botu.finance.payment.unionpay.sdk.DemoBase;
import com.bicon.botu.finance.payment.unionpay.sdk.LogUtil;
import lombok.extern.log4j.Log4j;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.Map;


/**
 * @Author: 宋旭
 * @Date: Created in 9:08 2017/8/1/001
 */
@Service
@Log4j
public class UnionPayService {

    /**
     * 银联全渠道平台发送订单推送请求
     *
     * @param unionpayDto 银联支付相关数据
     * @param orderNum    商户订单号
     * @param reqReserved 透传字段
     * @param money       订单金额
     * @return
     */
    public String payToUnion(UnionpayDto unionpayDto, String orderNum, String reqReserved, String money, Date time, String backUrl) {
        Map<String, String> rspData = UnionPayApi.payToUnionpay(unionpayDto, orderNum, money, reqReserved, backUrl, time);
        String tn = null;
        /**对应答码的处理，请根据您的业务逻辑来编写程序,以下应答码处理逻辑仅供参考------------->**/
        //应答码规范参考open.unionpay.com帮助中心 下载  产品接口规范  《平台接入接口规范-第5部分-附录》
        if (!rspData.isEmpty()) {
            if (AcpService.validate(rspData, DemoBase.encoding)) {
                LogUtil.writeLog("验证签名成功");
                String respCode = rspData.get("respCode");
                if (("00").equals(respCode)) {
                    //成功,获取tn号
                    tn = rspData.get("tn");
                }
            }
        }
        return tn;
    }

    public boolean queryToUnion(String merId, String orderNumber, Date txnTime) {
        Map<String, String> rspData = UnionPayApi.queryOrder(merId, orderNumber, txnTime);
        /**对应答码的处理，请根据您的业务逻辑来编写程序,以下应答码处理逻辑仅供参考------------->**/
        //应答码规范参考open.unionpay.com帮助中心 下载  产品接口规范  《平台接入接口规范-第5部分-附录》
        if (rspData.isEmpty()) {
            LogUtil.writeErrorLog("未获取到返回报文或返回http状态码非200");
        }
        if (AcpService.validate(rspData, DemoBase.encoding)) {
            LogUtil.writeLog("验证签名成功");
            if (("00").equals(rspData.get("respCode"))) {//如果查询交易成功
                String origRespCode = rspData.get("origRespCode");
                if (("00").equals(origRespCode)) {
                    //交易成功，更新商户订单状态
                    return true;
                } else {
                    //其他应答码为交易失败
                    return false;
                }
            } else {//查询交易本身失败，如应答码10/11检查查询报文是否正确
                return false;
            }
        } else {
            LogUtil.writeErrorLog("验证签名失败");
            return false;
        }
    }


    public boolean daifuToUnion(String merId, String orderNum, float total, String reqReserved, String backUrl, Date txnTime,
                                String remark, String identityCard, String payeeName, String payeeAccount) {
        Map<String, String> rspData = UnionPayApi.daifuToUnionpay(merId, orderNum, total, reqReserved, backUrl, txnTime, remark,
                identityCard, payeeName, payeeAccount);
        if (rspData.isEmpty()) {
            LogUtil.writeErrorLog("未获取到返回报文或返回http状态码非200");
            return false;
        }
        if (AcpService.validate(rspData, DemoBase.encoding)) {
            LogUtil.writeLog("验证签名成功");
            String respCode = rspData.get("respCode");
            if (("00").equals(respCode)) {
                //交易已受理(不代表交易已成功），等待接收后台通知确定交易成功，也可以主动发起 查询交易确定交易状态。
                return queryToUnion(merId, orderNum, txnTime);
                //如果返回卡号且配置了敏感信息加密，解密卡号方法：
                //String accNo1 = resmap.get("accNo");
                //String accNo2 = AcpService.decryptPan(accNo1, "UTF-8");	//解密卡号使用的证书是商户签名私钥证书acpsdk.signCert.path
                //LogUtil.writeLog("解密后的卡号："+accNo2);
            } else if (("03").equals(respCode) ||
                    ("04").equals(respCode) ||
                    ("05").equals(respCode) ||
                    ("01").equals(respCode) ||
                    ("12").equals(respCode) ||
                    ("34").equals(respCode) ||
                    ("60").equals(respCode)) {
                //后续需发起交易状态查询交易确定交易状态。
                return queryToUnion(merId, orderNum, txnTime);
            } else {
                //其他应答码为失败请排查原因
                return false;
            }
        } else {
            LogUtil.writeErrorLog("验证签名失败");
            return false;
        }
    }

}
